#pragma once
// 群组管理模块

#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/frame.hpp>
typedef websocketpp::server<websocketpp::config::asio> server;
typedef websocketpp::connection_hdl con_hdl;
typedef server::message_ptr msg_ptr;

#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <mysql/mysql.h>
#include <json/json.h>
#include <sstream>



#include "send_to_qml.hpp"
#include "FileManagement.hpp"
#include "UserManagement.hpp"



class GroupMgt
{
public:
    GroupMgt(){};
    ~GroupMgt(){};
    /// 工具类接口
    void mysql_my_init(MYSQL* &mysql);
    bool group_exist(std::string group_names);
    int insert_in_group(std::string name, int num, std::string avatar);
    void insert_in_group_rela(int user_id, int group_id, std::string rela);
    int group_id_of_name(std::string group_name);
    std::string info_of_group(int id, std::string colum);
    std::vector<int> ids_of_group(int group_id);

    /// 业务类接口
    void create_group(std::string group_names,std::string names,con_hdl hdl);
    void flush_qml_group_list(int user_id);
    void send_group_item_info_to_qml(int id, int group_id);
    void flush_group_info(int group_id, con_hdl hdl, server *s);
    
public:
    FileMgt file_mgt_;
};

bool GroupMgt::group_exist(std::string group_names)
{
    MYSQL* mysql;
    mysql_my_init(mysql);

    std::string query = 
    "SELECT COUNT(*) FROM `group` WHERE name = '" + group_names + "'";

    mysql_query(mysql, query.c_str());
    MYSQL_RES* result = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(result);
    int count = (row != nullptr) ? std::stoi(row[0]) : -1;
    
    if (count == 0 || count == -1)
    {
        std::cout << "GroupMgt::group_exist 群组 " << group_names << " 不存在, count = " << count << std::endl;
        mysql_free_result(result);
        mysql_close(mysql);
        return false;
    }
    else
    {
        std::cout << "GroupMgt::group_exist 群组 " << group_names << " 存在, count = " << count << std::endl;
        mysql_free_result(result);
        mysql_close(mysql);
        return true;
    }
       
    std::cout << "GroupMgt::group_exist 群组 " << group_names << " count 是未知的值" << std::endl;
    return false;
}

std::vector<int> GroupMgt::ids_of_group(int group_id)
{
    std::vector<int> ret;
    MYSQL* mysql;
    mysql_my_init(mysql);

    std::string query = 
    "SELECT user_id FROM group_relationship WHERE group_id = " + std::to_string(group_id) 
    + " AND relationship = '" + "member" + "'";

    mysql_query(mysql, query.c_str());
    MYSQL_RES* result = mysql_store_result(mysql);
    if(result != nullptr)
    {
        MYSQL_ROW row;
        while ((row = mysql_fetch_row(result)) != nullptr) 
        {
            // 遍历每一行的数据
            int member_id = atoi(row[0]);
            std::cout << "member_id: " << member_id << std::endl;
            ret.push_back(member_id);
        }
        mysql_free_result(result);
    }
    else
        std::cout << "result is null";

    return ret;
}

std::string GroupMgt::info_of_group(int id, std::string colum)
{
    // 设置数据库
    MYSQL* mysql;
    mysql_my_init(mysql);
    std::string ret = "";

    // 查询
    std::string query = "SELECT " + colum + " FROM `group` WHERE id = '" + std::to_string(id) + "'";
    mysql_query(mysql, query.c_str());
    MYSQL_RES* result = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row[0] == nullptr)
    {
        std::cout << "UserMgt::info_of_user 查询失败，字段：" << colum << std::endl;
    }
    else
    {
        ret = row[0];
    }
    
    mysql_free_result(result);
    mysql_close(mysql);

    return ret;
}

void GroupMgt::mysql_my_init(MYSQL* &mysql)
{
    mysql = mysql_init(nullptr); // mysql 可以被称为“句柄”
    if(mysql == nullptr)
        std::cerr << "mysql_init(nullptr) return null" << std::endl;
    if(mysql_real_connect(mysql,"127.0.0.1","qbt","134256","WSChat",
    8099,nullptr,0) == nullptr)
    {
        std::cerr << "数据库连接失败!!!" << std::endl;
        mysql_close(mysql);;
    }
    else
        mysql_set_character_set(mysql,"utf8");
}

int GroupMgt::insert_in_group(std::string name, int num, std::string avatar)
{
    MYSQL* mysql;
    mysql_my_init(mysql);

    std::string insert_query = 
    "INSERT INTO `group` (name, num_people, avatar) VALUES ('" +
    name + "', '" + std::to_string(num) + "', '" + 
    avatar + "')";

    // 执行插入语句
    int ret = mysql_query(mysql, insert_query.c_str());
    if (ret != 0)
    {
        std::cerr << "GroupMgt::insert_in_group 插入数据失败: " << mysql_error(mysql) << std::endl;
        mysql_close(mysql);
        return 0;
    }

    std::cout << "group 表中插入数据成功 " << name << " " << num  << " "<< avatar << std::endl;

    std::string query = "SELECT id FROM `group` WHERE name = '" + name + "'";
    mysql_query(mysql, query.c_str());
    MYSQL_RES* result = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row == nullptr)
    {
        std::cout << "GroupMgt::insert_in_group result is null" << std::endl;
        mysql_free_result(result);
        mysql_close(mysql);
        return 0;
    }
    else
        std::cout << "GroupMgt::insert_in_group select id " << std::stoi(row[0]) << std::endl;
    
    int id = std::stoi(row[0]);
    mysql_free_result(result);
    mysql_close(mysql);
    return id;
}

void GroupMgt::insert_in_group_rela(int user_id, int group_id, std::string rela)
{
    MYSQL* mysql;
    mysql_my_init(mysql);

    std::string insert_query = 
    "INSERT INTO group_relationship (user_id, group_id, relationship) VALUES ('" +
    std::to_string(user_id) + "', '" + std::to_string(group_id) + "', '" + 
    rela + "')";

    // 执行插入语句
    int ret = mysql_query(mysql, insert_query.c_str());
    if (ret != 0)
    {
        std::cerr << "GroupMgt::insert_in_group_rela 插入数据失败: " << mysql_error(mysql) << std::endl;
        mysql_close(mysql);
        return;
    }
    mysql_close(mysql);

    std::cout << "group_relationship 表中插入数据 " << user_id << " " << group_id  << " "<< rela << std::endl;
}

int GroupMgt::group_id_of_name(std::string group_name)
{
    MYSQL* mysql;
    mysql_my_init(mysql);

    std::string query = "SELECT id FROM `group` WHERE name = '" + group_name + "'";
    mysql_query(mysql, query.c_str());
    MYSQL_RES* result = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row == nullptr)
    {
        std::cout << "GroupMgt::group_id_of_name result is null" << std::endl;
        return 0;
    }
    else
        std::cout << "GroupMgt::group_id_of_name " << std::stoi(row[0]) << std::endl;
    int id = std::stoi(row[0]);
    mysql_free_result(result);
    mysql_close(mysql);
    return id;
}

void GroupMgt::create_group(std::string group_names, std::string names,con_hdl hdl)
{
    std::vector<std::string> nameList;

    // 使用字符串流解析字符串
    std::istringstream iss(names);
    std::string name;
    while (iss >> name) {
        nameList.push_back(name);
    }

    std::cout << group_names << std::endl;

    // 解析每个群成员的用户名
    int group_id = insert_in_group(group_names, nameList.size(), "");
    if (group_id == 0) return;
    for (const auto& name : nameList) 
    {
        int user_id = UserMgt::id_of_nickname(name);
        insert_in_group_rela(user_id, group_id, "member");   
    }

    Json::Value json_value;
    json_value["op"] = "popup_msg";
    json_value["kind"] = "yes";
    json_value["reason"] = "群组创建成功!";
    std::string str = json_value.toStyledString();
    send_to_qml::send_text(hdl, str);

    for (const auto& name : nameList) 
    {
        int user_id = UserMgt::id_of_nickname(name);
        flush_qml_group_list(user_id);
    }

    
}


void GroupMgt::flush_qml_group_list(int user_id)
{
    MYSQL* mysql;
    mysql_my_init(mysql);

    std::string query = 
    "SELECT group_id FROM group_relationship WHERE user_id = " + std::to_string(user_id) 
    + " AND relationship = '" + "member" + "'";

    mysql_query(mysql, query.c_str());
    MYSQL_RES* result = mysql_store_result(mysql);
    if(result != nullptr)
    {
        MYSQL_ROW row;
        while ((row = mysql_fetch_row(result)) != nullptr) 
        {
            // 遍历每一行的数据
            int group_id = atoi(row[0]);
            std::cout << "group_id: " << group_id << std::endl;
            send_group_item_info_to_qml(user_id, group_id);
        }
        mysql_free_result(result);
    }
    else
        std::cout << "result is null";
}

void GroupMgt::send_group_item_info_to_qml(int id, int group_id)
{
    Json::Value root;
    root["op"] = "have_group_item";
    root["id"] = group_id;
    std::string jsonString = root.toStyledString();
    if(UserMgt::is_user_online(UserMgt::nickname_of_id(id)))
        send_to_qml::send_text(UserMgt::hdl_of_user(UserMgt::nickname_of_id(id)), jsonString);
}

void GroupMgt::flush_group_info(int group_id, con_hdl hdl, server *s)
{
    // 查询群组的名称
    std::string group_name = info_of_group(group_id, "name");
    
    // 查询所有群组成员的id
    std::vector<int> ids = ids_of_group(group_id);

    std::string names_str = "";
    for (const auto& user_id : ids) 
    {
        names_str += UserMgt::nickname_of_id(user_id) + " ";
    }

    // 告诉客户端,用户的昵称等
    Json::Value root;
    root["op"] = "info";
    root["group_name"] = group_name;
    root["member_num"] = (int)ids.size();
    root["names_str"] = names_str;
    std::string jsonString = root.toStyledString();
    send_to_qml::send_text(hdl, jsonString);
	
    
    // 调用文件传输模块的方法, 把此 id 用户的头像, 发送到连接 hdl 上
    file_mgt_.send_group_avatar(group_id, hdl, s);
}